//
//  LevelScene.m
//  MessangerSkeleton
//
//  Created by User-23 on 4/17/14.
//  Copyright (c) 2014 IOTrainingCamp. All rights reserved.
//

#import "LevelScene.h"
#import "GamePlay.h"
#import "NetworkManager.h"

#import "MultiplayerGameScene.h"
#import "IntroScene.h"

#import "Configuration.h"

#import "AppDelegate.h"
#import "WaitingView.h"
#import "MessengerSprite.h"

@interface LevelScene () <UIAlertViewDelegate>

@property(nonatomic) GamePlay *gamePlay;
@property(nonatomic) NetworkManager *networkManager;

@property(nonatomic) id canceledOpponentObserver;
@property(nonatomic) id connectedPeerObserver;
@property(nonatomic) id disconnectedOpponentObserver;
@property(nonatomic) id receivedDataObserver;
@property(nonatomic) id playerChoosingCharacterObserver;
@property(nonatomic) id playerWaitingForEnemyForChoosingCharacterObserver;
@property(nonatomic) id opponentIsReadyToStartObserver;
@property(nonatomic) id playerIsReadyToStartObserver;
@property(nonatomic) id pingIsReveivedObserver;

@property(nonatomic) BOOL isCharacterChoosen;
@property(nonatomic) BOOL isPlayerReadyToStart;
@property(nonatomic) BOOL isOpponentReadyToStart;

@property(nonatomic) BOOL isMultiplayer;
@property(nonatomic) BOOL isPingReceived;

@end

@implementation LevelScene

#define kTextForButtonForFindingAnOpponent @"[ Find an opponent ]"
#define kTextForButtonMenu @"[ Menu ]"

#define kNameButtonForFindingAnOpponent @"findAnOpponentButton"
#define kNameRoute @"route"
#define kNamePlayer @"player"
#define kNameEnemy @"enemy"

#define kLevelOneButtonName @"[ Level One ]"
#define kLevelTwoButtonName @"[ Level Two ]"

#define kGoodCharacterButtonName @"GoodCharacter"
#define kBadCharacterButtonName @"BadCharacter"

#define kStartNameButtonName @"StartMultiplayerGame"

// -----------------------------------------------------------------------
#pragma mark - Create & Destroy
// -----------------------------------------------------------------------

+ (LevelScene *)scene
{
	return [[self alloc] init];
}

// -----------------------------------------------------------------------

- (id)init
{
    // Apple recommend assigning self with supers return value
    self = [super init];
    if (!self) return(nil);


    self.gamePlay = [GamePlay sharedInstance];
    
    CCSprite* background = [CCSprite spriteWithImageNamed:@"titleScreenFull.png"];
    [background setAnchorPoint: CGPointZero];
    [background setPosition:CGPointZero];
    [background setScale:0.95];
    [self addChild:background];
    
    NSLog(@"self.gamePlay.gameState = %d", self.gamePlay.gameState);
    
    //TODO - update levels
    if ( self.gamePlay.gameState == kGameStateLaunchedSinglePlayer )
    {
        [self showButtonsForLevelsSingleplayer];
    
    }else if ( self.gamePlay.gameState == kGameStateLaunchedMultiPlayer )
    {
        NSLog(@"multiplayer");
        self.networkManager = [NetworkManager sharedInstance];
        self.isMultiplayer = YES;
        self.isPlayerReadyToStart = NO;
        self.isOpponentReadyToStart = NO;

        [self.networkManager startLookingForOponent];
    }
    
    // Create a back button
    CCButton *menuButton = [CCButton buttonWithTitle:kTextForButtonMenu fontName:kSceneButtonFontNameVerdanaBold fontSize:18.0f];
    menuButton.positionType = CCPositionTypeNormalized;
    menuButton.position = ccp(0.85f, 0.95f); // Top Right of screen
    [menuButton setColor:KSceneButtonFontColor];
    [menuButton setTarget:self selector:@selector(pressedMenuButton:)];
    [self addChild:menuButton];


    

    
    // done
	return self;
}


- (void)onEnter
{
    [super onEnter];
    if ( self.isMultiplayer && !self.networkManager.areObserversOnLevelSceneAdded ){
        [self addObserversToScene];
    }
}

- (void)onExit
{
    NSLog(@"exit levelscene");
    
    [super onExit];
    if ( self.isMultiplayer && self.networkManager.areObserversOnLevelSceneAdded ){
        [self removeObserversFromScene];
    }
}

// -----------------------------------------------------------------------
#pragma mark - Button Callbacks
// -----------------------------------------------------------------------

- (void)pressedMenuButton:(id)sender
{
    [self goBackToIntroScene];
}

- (void)goBackToIntroScene
{
    if ( self.gamePlay.gameState != kGameStateLaunchedSinglePlayer  ){
        if ( !self.networkManager.isAlertViewDisplayedEndConnection ){
            [self.networkManager endSession];
        }
        self.networkManager.isAlertViewDisplayedEndConnection = NO;
        [self removeWaitingView];
    }
    [[CCDirector sharedDirector] replaceScene:[IntroScene scene]
                               withTransition:[CCTransition transitionPushWithDirection:CCTransitionDirectionInvalid duration:1.0f]];
}

- (MessengerSpriteType)getCharacterForTheOpponent
{
    if (self.gamePlay.characterType == kMessengerSelf ) {
        
        return kMessengerEnemy;
    }
    return kMessengerSelf;
}

#pragma mark - Singleplayer
- (void)showButtonsForLevelsSingleplayer
{
    CCButton *levelOneButton = [CCButton buttonWithTitle:kLevelOneButtonName fontName:kSceneButtonFontNameVerdanaBold fontSize:18.0f];
    levelOneButton.positionType = CCPositionTypeNormalized;
    levelOneButton.position = ccp(0.5f, 0.65f);
    levelOneButton.name = kLevelOneButtonName;
    [levelOneButton setColor:KSceneButtonFontColor];
    [levelOneButton setTarget:self selector:@selector(playLevel:)];
    [self addChild:levelOneButton];
    
    CCButton *levelTwoButton = [CCButton buttonWithTitle:kLevelTwoButtonName fontName:kSceneButtonFontNameVerdanaBold fontSize:18.0f];
    levelTwoButton.positionType = CCPositionTypeNormalized;
    levelTwoButton.position = ccp(0.5f, 0.45f);
    levelTwoButton.name = kLevelTwoButtonName;
    [levelTwoButton setColor: KSceneButtonFontColor];
    [levelTwoButton setTarget:self selector:@selector(playLevel:)];
    [self addChild:levelTwoButton];
    
//    [[NSUserDefaults standardUserDefaults] setFloat:23.3f forKey:@"2"];
    if ([[NSUserDefaults standardUserDefaults]integerForKey:@"1"] == 0) {
        levelTwoButton.enabled = NO;
    }else {
//        NSLog(@"%d",)
    }
}

- (void)playLevel:(id)sender
{
    if ( [sender isKindOfClass:[CCButton class]] ){
        CCButton *pressedButton = sender;
        SWITCH(pressedButton.title) {
            CASE(kLevelOneButtonName){
                //TODO - set current Level/format?
                self.gamePlay.level = 1;
                break;
            }
            CASE(kLevelTwoButtonName){
                self.gamePlay.level = 2;
                break;
            }
            DEFAULT {
                break;
            }
        }
        if ( self.gamePlay.gameState == kGameStateLaunchedSinglePlayer ){
            self.gamePlay.gameState = kGameStatePlaying;
            [[CCDirector sharedDirector] replaceScene:[GameScene sceneWithLevel:self.gamePlay.level]
                                       withTransition:[CCTransition transitionPushWithDirection:CCTransitionDirectionLeft duration:1.0f]];
        }
    }
}

#pragma mark - Multiplayer

- (void)showButtonsForChoosingACharacter
{
    CCButton *goodCharacterButton = [CCButton buttonWithTitle:@"[ the good one ]" fontName:kSceneButtonFontNameVerdanaBold fontSize:18.0f];
    goodCharacterButton.positionType = CCPositionTypeNormalized;
    goodCharacterButton.position = ccp(0.7f, 0.5f);
    goodCharacterButton.name = kGoodCharacterButtonName;
    [goodCharacterButton setColor:KSceneButtonFontColor];
    [goodCharacterButton setTarget:self selector:@selector(chooseCharacter:)];
    [self addChild:goodCharacterButton];
    
    CCButton *badCharacterButton = [CCButton buttonWithTitle:@"[ the bad one ]" fontName:kSceneButtonFontNameVerdanaBold fontSize:18.0f];
    badCharacterButton.positionType = CCPositionTypeNormalized;
    badCharacterButton.position = ccp(0.3f, 0.5f);
    badCharacterButton.name = kBadCharacterButtonName;
    [badCharacterButton setColor:KSceneButtonFontColor];
    [badCharacterButton setTarget:self selector:@selector(chooseCharacter:)];
    [self addChild:badCharacterButton];
    
}

- (void)showButtonForStartingGame
{
    CCButton *startGameButton = [CCButton buttonWithTitle:@"[ lets play! ]" fontName:kSceneButtonFontNameVerdanaBold fontSize:18.0f];
    startGameButton.positionType = CCPositionTypeNormalized;
    startGameButton.position = ccp(0.5f, 0.4f);
    startGameButton.name = kStartNameButtonName;
    [startGameButton setColor:KSceneButtonFontColor];
    [startGameButton setTarget:self selector:@selector(startGame)];
    [self addChild:startGameButton];
}


- (void)multiplayerShowButtonsForLevels
{
    NSLog(@"adding button for Level 1");
    CCButton *levelOneButton = [CCButton buttonWithTitle:@"[ level one ] " fontName:@"Verdana-Bold" fontSize:18.0f];
    levelOneButton.positionType = CCPositionTypeNormalized;
    levelOneButton.position = ccp(0.5f, 0.8f);
    levelOneButton.name = kLevelOneButtonName;
    [levelOneButton setColor:KSceneButtonFontColor];
    [levelOneButton setTarget:self selector:@selector(multiplayerPlayLevel:)];
    [self addChild:levelOneButton];
    [self.children enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        if ( [obj isKindOfClass:[CCButton class]] )
        {
            NSLog(@"button obj = %@",obj);
        }
        else{
            NSLog(@"obj = %@ is not a button",obj);
        }
    }];
}

- (void)playGameIfBothAreReady
{
    NSLog(@"both are ready");
    if ( self.isPlayerReadyToStart && self.isOpponentReadyToStart ) {
        
        [self removeWaitingView];
        
        self.gamePlay.gameState = kGameStateMultiPlayerPlaying;
        [[CCDirector sharedDirector] replaceScene:[MultiplayerGameScene sceneWithLevel:self.gamePlay.level]
                                   withTransition:[CCTransition transitionPushWithDirection:CCTransitionDirectionInvalid duration:1.0f]];
    }
}

- (void)playGameIfBothAreReadyWithDelay:(NSTimeInterval)delay
{
   [self performSelector:@selector(playGameIfBothAreReady) withObject:nil afterDelay:delay];
}

- (void)startGame
{
    if ( self.isCharacterChoosen && self.gamePlay.level>0  )
    {
        if ( self.isPingReceived ){
            [self.networkManager sendToOpponentLevel:self.gamePlay.level andCharacterType:[self getCharacterForTheOpponent]];
            [self.networkManager sendThatThePlayerIsReadyToPlay];
            self.isPlayerReadyToStart = YES;
            NSLog(@"ping is %f", [self.networkManager ping]);
            [self playGameIfBothAreReadyWithDelay:[self.networkManager ping]/2];
        }else{
            [self playerIsWaitingForOpponentToReceiveData];
        }
    }
}

- (void)chooseCharacter:(id)sender
{
    if ( [sender isKindOfClass:[CCButton class]] ){
        CCButton *pressedButton = sender;
        
        
        if ( [pressedButton.name isEqualToString:kGoodCharacterButtonName] )
        {
            self.gamePlay.characterType = kMessengerSelf;
            self.isCharacterChoosen = YES;
        
        }else if  ( [pressedButton.name isEqualToString:kBadCharacterButtonName] )
        {
            self.gamePlay.characterType = kMessengerEnemy;
            self.isCharacterChoosen = YES;
        }
    }
}

- (void)multiplayerPlayLevel:(id)sender
{
    if ( [sender isKindOfClass:[CCButton class]] ){
        CCButton *pressedButton = sender;
        
        if ( [pressedButton.name isEqualToString:kLevelOneButtonName] )
        {
            self.gamePlay.level = 1;
        }
    }
    
}


//TODO - opponent is choosing level and character
- (void)opponentIsChoosingLevelAndCharacter
{
    int margin = 40;
    CGRect frame = [[UIScreen mainScreen] bounds];
    CGSize tempSize = CGSizeMake(frame.size.height, frame.size.width);
    frame.size.width = tempSize.width;
    frame.size.height = tempSize.height;
    frame.origin.x = margin/2;
    frame.origin.y = -margin/2;

    WaitingView *waitingView = [[WaitingView alloc] initWithFrame:frame];
    AppDelegate *appDel = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    [appDel.window.rootViewController.view addSubview:waitingView];
    
    waitingView.center = waitingView.superview.center;
    
    waitingView.messageTextView.text = kMessageViewOpponentChoosesLevelAndCharacter;
    waitingView.tag = 10;
    
    [waitingView.quitButton addTarget:self action:@selector(quitOpponentChoosingLevelAndCharacter:) forControlEvents:UIControlEventTouchUpInside];
}

- (void)playerIsWaitingForOpponentToReceiveData
{
    
    CGRect frame  = [self boundingBox];
    AppDelegate *appDel = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    WaitingView *waitingView = [[WaitingView alloc] initWithFrame:CGRectMake(0,0, frame.size.width, frame.size.height)];
    [appDel.window.rootViewController.view addSubview:waitingView];
    
    waitingView.messageTextView.text = @"Please, wait...";
    waitingView.tag = 10;
    
    [waitingView.quitButton addTarget:self action:@selector(quitOpponentChoosingLevelAndCharacter:) forControlEvents:UIControlEventTouchUpInside];
}

- (void)quitOpponentChoosingLevelAndCharacter:(id)sender
{
    [[sender superview] removeFromSuperview];
    [self goBackToIntroScene];
}


- (void)removeWaitingView
{
    AppDelegate *appDel = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    NSArray *allSubviews = [appDel.window.rootViewController.view subviews];
    
    [allSubviews enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        if ( [obj tag] == 10 )
        {
            [obj removeFromSuperview];
        }
    }];
}

#pragma mark - add observers
- (void)addObserversToScene
{
    NSLog(@"Observers are added");
    self.networkManager.areObserversOnLevelSceneAdded = YES;
    
    self.canceledOpponentObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kNetworkNotificationNameForCanceledLookingForAnOpponent object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
        
        self.networkManager.isBrowserPresented = NO;
        [self goBackToIntroScene];
        NSLog(@"pressed cancel - notification block");
    }];
    
    self.connectedPeerObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kNetworkNotificationNameForConnectedPeer object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
        
        self.networkManager.isBrowserPresented = NO;
        NSLog(@"connected to peer - notification block");
    }];
    
    self.disconnectedOpponentObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kNetworkNotificationNameForDisconnectedOpponent object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
        
        [self goBackToIntroScene];
        NSLog(@"peer is disconnected - notification block");
    }];
    
    self.receivedDataObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kNetworkNotificationNameForReceivedData object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
        NSLog(@"received data - notification block");
    }];
    
    self.playerChoosingCharacterObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kNetworkNotificationNamePlayerChoosingCharacter object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
        NSLog(@"playerChoosingCharacterObserver - notification block");
        [self multiplayerShowButtonsForLevels];
        [self showButtonsForChoosingACharacter];
        [self showButtonForStartingGame];
        
    }];
    
    self.opponentIsReadyToStartObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kNetworkNotificationNameOpponentIsReadyToStart object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
        NSLog(@"opponentIsReadyToStartObserver - notification block");
        
        self.isOpponentReadyToStart = YES;
        [self playGameIfBothAreReady];
    }];
    
    self.playerIsReadyToStartObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kNetworkNotificationNamePlayerIsReadyToStart object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
        NSLog(@"opponentIsReadyToStartObserver - notification block");
        self.isPlayerReadyToStart = YES;
        [self.networkManager sendThatThePlayerIsReadyToPlay];
        [self playGameIfBothAreReady];
    }];
    

    self.playerWaitingForEnemyForChoosingCharacterObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kNetworkNotificationNamePlayerWaitingForEnemyForChoosingCharacter object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
        
        [self opponentIsChoosingLevelAndCharacter];
        
        NSLog(@"playerWaitingForEnemyForChoosingCharacterObserver - notification block");
    }];
    
    self.pingIsReveivedObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kNetworkNotificationNamePingIsReceived object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
        
        self.isPingReceived = YES;
        [self startGame];
        
        NSLog(@"pingIsReveivedObserver - notification block");
    }];
}

#pragma mark - remove observers
- (void)removeObserversFromScene
{
    self.networkManager.areObserversOnLevelSceneAdded = NO;
    [[NSNotificationCenter defaultCenter] removeObserver:self.canceledOpponentObserver];
    [[NSNotificationCenter defaultCenter] removeObserver:self.connectedPeerObserver];
    [[NSNotificationCenter defaultCenter] removeObserver:self.disconnectedOpponentObserver];
    [[NSNotificationCenter defaultCenter] removeObserver:self.receivedDataObserver];
    [[NSNotificationCenter defaultCenter] removeObserver:self.playerChoosingCharacterObserver];
    [[NSNotificationCenter defaultCenter] removeObserver:self.opponentIsReadyToStartObserver];
    [[NSNotificationCenter defaultCenter] removeObserver:self.playerIsReadyToStartObserver];
    [[NSNotificationCenter defaultCenter] removeObserver:self.playerWaitingForEnemyForChoosingCharacterObserver];
    [[NSNotificationCenter defaultCenter] removeObserver:self.pingIsReveivedObserver];
    
    NSLog(@"Observers are removed");
}


@end
